//
// Created by Gorun on 2022/5/6.
//

#include "LoxClass.h"
#include "LoxInstance.h"
#include "LoxFunction.h"
#include <utility>

using namespace std;

LoxClass::LoxClass(string name, shared_ptr<LoxClass> superclass, map<string, shared_ptr<LoxFunction>> methods)
: name{move(name)}, superclass{move(superclass)}, methods{move(methods)}
{}

string LoxClass::toString() {
    return name;
}

any LoxClass::call(Interpreter &interpreter, vector<any> arguments) {
    auto instance = make_shared<LoxInstance>(shared_from_this());
    shared_ptr<LoxFunction> initializer = findMethod("init");
    if (initializer!=nullptr) {
        initializer->bind(instance)->call(interpreter, arguments);
    }
    return instance;
}

int LoxClass::arity() {
    shared_ptr<LoxFunction> initializer = findMethod("init");
    if (initializer==nullptr) return 0;
    else return initializer->arity();
}

shared_ptr<LoxFunction> LoxClass::findMethod(string name) {
    auto element = methods.find(name);
    if (element!=methods.end()) {
        return element->second;
    }

    if (superclass!=nullptr) {
        return superclass->findMethod(name);
    }

    return nullptr;
}
